# 函数代码块 以def为关键词，后接方法名称和形参
# 函数的第一行代码使用字符串做备注？？？？
# 不可变对象 string number tuple 在方法内单独修改不影响传入的形参
# 其余则会影响
import datetime
from typing import Optional, Union, Any


#year: Optional[int]=None  可选int 不传为None
#year: Union[int, None] 必须传入形参即使参数为None
#year: Union[int] 不能为空,即使参数为None也不行
#year: Union[int]=None 等价于这个用法
#year: Union[int]=2026 指定默认值
def usable(datetime_obj:datetime.datetime,year: Union[int]=None):
    """
    替换 datetime 对象的年份，默认替换为 2024

    :param year:
    :param datetime_obj:
    :return: 替换后的新datetime 对象

    """
    #datetime 即是模块名 也是类名
    if not isinstance(datetime_obj, datetime.datetime):
        raise ValueError("第一个参数必须是datetime对象")
    if not None and isinstance(datetime_obj, int):
        raise ValueError("第一个参数必须是int")
    if year is None:
        year = 2024
    #datetime.replace() 方法 不会修改原对象
    return datetime_obj.replace(year=year)

# 位置不定长参数 也称为可变位置参数
# 允许函数接受任意数量的位置参数，这些参数会被收集到一个元组(tuple)中。在参数名前加一个星号(*)来表示这是不定长位置参数
# Python 3.5+ 声明返回类型为int
def position_variable_args(*args:int) ->Union[int,None]:
    """
    数字进行累加
    :param args: 数字
    :return
    :int 合
    :None 形参为空
    """
    total=0
    for arg in args:
        total+=arg
    return total



# 不定长关键字参数
# 允许函数接受任意数量的关键字参数（key=value 形式），这些参数会被收集到一个字典（dict）中。
# kwargs 是 "keyword arguments" 的缩写，但可以自定义名称
def keyword_variable_args(**kwargs: Any) :
    """

    :param kwargs:
    :return:
    """

    for k,v in kwargs.items():
        print(k)
        print(v)

# 强制后面的参数必须用关键字传递,也就是形参名
#
def keyword(name,*,birthday:str):
    print(name,birthday)

# 位置可变参数和关键字可变参数 混用
# **kwargs位置必须在最后
# 必选参数 →
# 默认参数=2024，可以省略 →
# 位置可变参数（*args）捕获所有剩余的位置参数，形成一个元组 →
# 关键字参数（*） 强制其后的参数必须通过关键字传递（* 本身不接收参数）和关键字可变参数 二选一 →
# 关键字可变参数（**kwargs）捕获所有剩余的关键字参数，形成一个字典
#
def union_variable_args(year,month,day=1,*args,**kwargs):
    print(year,month,day)
    position_variable_args(*args)
    keyword_variable_args(**kwargs)

if __name__ == '__main__':
    #print(usable(datetime.datetime.now()))
    #print(position_variable_args(0,1,2,3,4))

    #不定长关键字参数
    #字典传递
    keyword_variable_args(**{'name': 'taishan', '2': 'v2', '3': 3})
    keyword_variable_args(name="taishan",post="guangdong",boss="ye xuan ning")

    #关键字参数
    # keyword('dengxiaop',birthday="1992-05-04")
    # 可迭代对象解包 *(0,1,2,3,4)  day被接包后的0覆盖了
    union_variable_args(2025,10,*(0,1,2,3,4),name="taishan",post="guangdong",boss="ye xuan ning")
    pass


